package com.onmicro.snc_ble.core.bluetooth;

import android.os.Build;
import android.os.Handler;
import android.provider.Settings;
import android.util.Log;

import com.onmicro.snc_ble.app.App;
import com.onmicro.snc_ble.common.PreferenceUtils;

/**
 * @author PengYaQuan
 * @create 2019-11-05 15:47
 * @Describe
 */
public class OmrBluetoothManager {
    private static final String TAG = OmrBluetoothManager.class.getName();

    private String mGroupId;
    private char[] mPhoneId;
    private BeaconTransmitter mBeaconTransmitter;
    private long mRecordTime;

    private Handler mHandler = null;
    private int mSn = 0;
    private int mValue = 0;
    private int mValue1 = 0;
    //private byte[] mOmrRfAddr = {(byte) 0x98, 0x43, (byte) 0xaf, 0x0b, 0x46};
    private byte[] mOmrRfAddr = {0x52, (byte)0x9c, 0x54, 0x6e, 0x55};
    private byte[] mAdvertisingData = new byte[18];
    private static OmrBluetoothManager instance;

    private OmrBluetoothManager() {
        String androidId = PreferenceUtils.getValue(App.getInstance(), "ANDROID_ID");
        if (androidId.length() == 0) {
            androidId = Settings.Secure.getString(App.getInstance().getContentResolver(), "android_id");
            androidId += Build.SERIAL;
            if (androidId.length() < 3) {
                androidId = "FFFF";
            } else {
                androidId = androidId.substring(0, 4);
            }
            PreferenceUtils.putValue(App.getInstance(), "ANDROID_ID", androidId);
        }
        Integer value = Integer.valueOf(androidId, 16);
        mPhoneId = new char[]{(char) (0xFF00 & value >> 8), (char) (value & 0xFF)};
        mHandler = new Handler();
        mBeaconTransmitter = new BeaconTransmitter(App.getInstance());
    }

    public static OmrBluetoothManager getInstance() {
        if (instance == null) {
            synchronized (OmrBluetoothManager.class) {
                if (instance == null) {
                    instance = new OmrBluetoothManager();
                }
            }
        }
        return instance;
    }

    public void setGroupId(String groupId) {
        mGroupId = groupId;
    }

    private void startAdvertising(char command, char[] data) {
        String groupId;
        if (mGroupId == null || mGroupId.length() == 0) {
            groupId = "FF";
        } else {
            groupId = mGroupId;
        }
        int intGroupId = Integer.valueOf(groupId, 16);
        if (mSn >= 255) {
            mSn = 0;
        }
        mSn++;
        Log.e(TAG, "原始数据:" + mSn);
        char[] payloadData = new char[8];
        payloadData[0] = mPhoneId[0];
        payloadData[1] = mPhoneId[1];
        payloadData[2] = (char) intGroupId;
        payloadData[3] = command;
        payloadData[4] = (char) mSn;
        payloadData[5] = data[0];
        payloadData[6] = data[1];
        payloadData[7] = data[2];

        byte[] bytesPayloadData = charArrToByteArr(payloadData);

        OmrUtils.getRfPayload(mOmrRfAddr, mOmrRfAddr.length, bytesPayloadData, bytesPayloadData.length, mAdvertisingData);
        mBeaconTransmitter.startAdvertising(mAdvertisingData);
        Log.e(TAG, "sendBytes start:" + OmrUtils.getHexString(mAdvertisingData, ":"));

        if (mHandler != null) {
            mHandler.removeMessages(0);
            mHandler.postDelayed(() -> {
                mBeaconTransmitter.stopAdvertising();
                Log.e(TAG, "sendBytes stop:" + OmrUtils.getHexString(mAdvertisingData, ":"));
            }, 3000);
        }
    }

    private void startAdvertisingInterval(char paramChar, char[] paramArrayOfChar, long paramLong) {
        if (System.currentTimeMillis() - this.mRecordTime > paramLong) {
            this.mRecordTime = System.currentTimeMillis();
            new Thread(() -> startAdvertising(paramChar, paramArrayOfChar)).start();
        }
    }

    /**
     * 控制
     */
    public void clearCode() {
        startAdvertising((char)0xB0, new char[]{0, 0, 0});
    }

    public void close() {
        startAdvertising((char) 0xB2, new char[]{0, 0, 0});
    }

    public void open() {
        startAdvertising((char) 0xB3, new char[]{0, 0, 0});
    }

    public void pairCode() {
        startAdvertising((char)0xB4, new char[]{0, 0, 0});
    }

    public void setBeganBrightness(int paramInt) {
        startAdvertisingInterval((char)0xB5, new char[]{(char) ((0xFF0000 & paramInt) >> 16), (char) ((0xFF00 & paramInt) >> 8), (char) (paramInt & 0xFF)}, 100L);
    }

    public void setBeganColorTemperature(int paramInt) {
        startAdvertisingInterval((char)0xB7, new char[]{(char) ((0xFF0000 & paramInt) >> 16), (char) ((0xFF00 & paramInt) >> 8), (char) (paramInt & 0xFF)}, 100L);
    }

    public void setCancelTiming(int paramInt1, int paramInt2, int paramInt3) {
        startAdvertising('U', new char[]{(char) paramInt1, (char) paramInt2, (char) paramInt3});
    }

    public void setEndedBrightness(int paramInt) {
        startAdvertising((char)0xB5, new char[]{(char) ((0xFF0000 & paramInt) >> 16), (char) ((0xFF00 & paramInt) >> 8), (char) (paramInt & 0xFF)});
    }

    public void setEndedColorTemperature(int paramInt) {
        startAdvertising((char)0xB7, new char[]{(char) ((0xFF0000 & paramInt) >> 16), (char) ((0xFF00 & paramInt) >> 8), (char) (paramInt & 0xFF)});
    }

    public void setFanIndex(int paramInt) {
        switch (paramInt) {
            case 0:
                startAdvertising((char)0xD8, new char[]{0, 0, 0});
                break;
            case 1:
                startAdvertising((char)0xD2, new char[]{0, 0, 0});
                break;
            case 2:
                startAdvertising((char)0xD1, new char[]{0, 0, 0});
                break;
            default:
                startAdvertising((char)0xD0, new char[]{0, 0, 0});
                break;
        }
    }

    public void setFanMoreModes(int paramInt) {
        switch (paramInt) {
            case 0:
                startAdvertising((char)0xA3, new char[]{255, 255, 0});
                break;
            case 1:
                startAdvertising((char)0xA2, new char[]{0, 255, 0});
                break;
            case 2:
                startAdvertising((char)0xA4, new char[]{123, 123, 0});
                break;
            case 3:
                startAdvertising((char)0xA1, new char[]{25, 25, 0});
                break;
            case 4:
                if (mValue1 >= 2) {
                    mValue1 = 0;
                }
                mValue1++;
                startAdvertising((char)0xA6, new char[]{(char) this.mValue1, '\000', '\000'});
                break;
            case 5:
                break;
            case 6:
                if (mValue >= 3) {
                    mValue = 0;
                }
                mValue++;
                startAdvertising((char)0xA7, new char[]{(char) this.mValue, '\000', '\000'});
                break;
            case 7:
                startAdvertising((char)0xD4, new char[]{0, 0, 0});
                break;
            case 8:
                startAdvertising((char)0xD5, new char[]{0, 0, 0});
                break;
            case 9:
                startAdvertising((char)0xD6, new char[]{0, 0, 0});
                break;
            case 10:
                startAdvertising((char)0xD7, new char[]{0, 0, 0});
                break;
            case 11:
                startAdvertising((char)0xDA, new char[]{0, 0, 0});
                break;
            default:
                startAdvertising((char)0xD9, new char[]{0, 0, 0});
                break;
        }
    }

    public void setMoreModes(int paramInt) {
        switch (paramInt) {
            case 0:
                startAdvertising((char)0xA3, new char[]{255, 255, 0});
                break;
            case 1:
                startAdvertising((char)0xA2, new char[]{0, 255, 0});
                break;
            case 2:
                startAdvertising((char)0xA4, new char[]{123, 123, 0});
                break;
            case 3:
                startAdvertising((char)0xA1, new char[]{25, 25, 0});
                break;
            case 4:
                if (mValue1 >= 2) {
                    mValue1 = 0;
                }
                mValue1++;
                startAdvertising((char)0xA6, new char[]{(char) this.mValue1, '\000', '\000'});
                break;
            case 5:
                break;
            case 6:
                if (mValue >= 3) {
                    mValue = 0;
                }
                mValue++;
                startAdvertising((char)0xA7, new char[]{(char) this.mValue, '\000', '\000'});
                break;
            case 7:
                startAdvertising((char)0xA8, new char[]{0, 0, 0});
                break;
            case 8:
                startAdvertising((char)0xA9, new char[]{0, 0, 0});
                break;
            default:
                break;
        }
    }

    public void setTiming(int paramInt1, int paramInt2, int paramInt3) {
        startAdvertising((char)0xA5, new char[]{(char) paramInt1, (char) paramInt2, (char) paramInt3});
    }

    private byte[] charArrToByteArr(char[] src) {
        byte[] bytes = new byte[src.length];
        for (int i = 0; i < src.length; i++) {
            bytes[i] = (byte) src[i];
        }
        return bytes;
    }
}
